package apobates.gui.formatter.service;

import apobates.gui.formatter.component.SourceLoaderLayout;
import com.google.common.base.Splitter;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.scene.layout.AnchorPane;
import org.fxmisc.richtext.StyledTextArea;
import org.reactfx.Change;
import org.reactfx.EventStream;
import org.reactfx.EventStreams;
import java.util.List;

/**
 * 针对大内容的自定义渲染. 使用切片的形式
 */
public class SourceContentRender {
    private final String content;
    private final AnchorPane anchorPane;
    private final int pearWriteSize ;
    private SimpleBooleanProperty contentloaded;
    // https://edencoding.com/force-refresh-scene/
    // https://www.coder.work/article/1800405
    public SourceContentRender(String content, AnchorPane textAreaParent){
        this(content, textAreaParent, 10000);
    }

    public SourceContentRender(String content, AnchorPane textAreaParent, int pearWriteSize) {
        this.content = content;
        this.anchorPane = textAreaParent;
        this.pearWriteSize = pearWriteSize;
        this.contentloaded = new SimpleBooleanProperty(false);
    }

    // http://localhost/oemp-api/public/index.php/fund/mte
    public void render() {
        int contentLength = content.length();
        // ::RichTextFX::
        StyledTextArea area = (StyledTextArea) anchorPane.getChildren().get(0);
        // 每次都清空@20230417
        area.clear();
        if(contentLength <= this.pearWriteSize) {
            this.fillTextAreaContent(area);
            this.contentloaded.setValue(true);
        }else{
            List<String> stringList = Splitter.fixedLength(this.pearWriteSize).splitToList(content);
            this.executeAsyncTask(area, stringList);
        }
    }
    public EventStream<Change<Boolean>> stream(){
        return EventStreams.changesOf(contentloaded);
    }
    public SimpleBooleanProperty getContentloaded(){
        return this.contentloaded;
    }
    private void fillTextAreaContent(StyledTextArea area){
        // InlineCssTextArea
        System.out.println("[SCR]fill all start");
        // ::RichTextFX::
        // StyledTextArea area = (StyledTextArea) anchorPane.getChildren().get(0);
        area.appendText(content);
    }
    private void executeAsyncTask(StyledTextArea area, List<String> stringList){
        System.out.println("[SCR]fill segment start");
        // ::RichTextFX::
        // StyledTextArea area = (StyledTextArea) anchorPane.getChildren().get(0);
        final int result = stringList.size();
        Task <Void> t = new Task <Void> () {
            @Override
            protected Void call() throws Exception {
                for (int i = 0; i < result; i++) {
                    String tmp = stringList.get(i);
                    Platform.runLater(()->{
                        area.appendText(tmp);
                    });
                    updateProgress(i, result);
                    Thread.sleep(1000);
                }
                return null;
            }
        };
        // ::进度提示::
        // ::遮盖层::
        // ::WRAP::
        final SourceLoaderLayout sll =new SourceLoaderLayout(this.anchorPane.getWidth(), this.anchorPane.getHeight());
        sll.show(this.anchorPane);
        sll.bind(t.progressProperty());
        //
        Thread curThread = new Thread(t);
        curThread.start(); // right
        t.setOnSucceeded((WorkerStateEvent workerStateEvent)-> {
            // ::进度提示::
            // ::遮盖层::
            // ::WRAP::
            sll.close(this.anchorPane);
            this.contentloaded.setValue(true);
            System.out.println("[SCR]is-Alive: "+curThread.isAlive()+", is-interupt: "+curThread.isInterrupted()+", is-deamon: "+curThread.isDaemon());
        });

    }
}
